<script setup>
import {onMounted, reactive, ref} from "vue";
import {
  cancelEnrollContestService,
  cancelRemindContestService,
  createEnrollContestService,
  createRemindContestService,
  pageContestService,
  someRemindContestService
} from "@/api/contest.js";
import {ElMessage, ElMessageBox} from "element-plus";
import router from "@/router/index.js";

//题目列表
const contestList = ref([])
const totalSize = ref(0)
const selectedOption = ref(0);
const options = ref([
  {label: '未开始竞赛', value: 0},
  {label: '进行中竞赛', value: 1},
  {label: '历史竞赛', value: 2}
])

// 弹出框显示状态
const reminderDialogVisible = ref(false);

// 预约时间类型表单数据
const reminderForm = reactive({
  notificationMethod: '',
  reminderTime: '',
});

// 可选提醒时间
const reminderTimes = [10, 20, 30, 40, 50, 60];

// 默认请求 -未开始的竞赛
const params = reactive({
  current: 1,
  size: 9,
  beginTime: "",
  endTime: "",
  type: 0
})

async function getContestList() {
  const result = await pageContestService(params)
  contestList.value = result.data.records
  totalSize.value = result.data.total
}

onMounted(() => {
  getContestList()
})

// 当选中不同的竞赛类型的时候
function selectOption(type) {
  selectedOption.value = type
  params.current = 1
  params.type = type
  getContestList()
}

// 已开赛标签 - beginTime < now < endTime && 未报名 && 进行中竞赛
function isOngoingAndUnregisteredCompetition(exam) {
  const now = new Date();
  return new Date(exam.beginTime) < now && new Date(exam.endTime) > now && !exam.isEnroll && selectedOption.value === 1
}

// 开始答题 - beginTime < now < endTime && 已报名 && 进行中竞赛
function isStartExam(exam) {
  const now = new Date();
  return new Date(exam.beginTime) < now && new Date(exam.endTime) > now && exam.isEnroll && selectedOption.value === 1;
}

// 预约竞赛提醒 - beginTime > now && 已报名 && 未开始的竞赛
function isEnrollContest(contest) {
  const now = new Date();
  return new Date(contest.beginTime) > now && contest.isEnroll && selectedOption.value === 0
}

// 取消报名竞赛 -  beginTime > now && 已报名 && 未开始的竞赛
function isCancelEntry(contest) {
  const now = new Date();
  return new Date(contest.beginTime) > now && contest.isEnroll && selectedOption.value === 0
}

// 查看比赛结果详情 - endTime < now && 历史竞赛
function checkContestRanking(contest) {
  const now = new Date();
  return new Date(contest.endTime) < now && selectedOption.value === 2
}

// 报名参赛 - beginTime > now && 未报名 && 未开始的竞赛
function isCanEntry(exam) {
  const now = new Date();
  return new Date(exam.beginTime) > now && !exam.isEnroll && selectedOption.value === 0;
}

// 判断是否已经交卷逻辑 - beginTime < now < endTime && 已报名 && 进行中竞赛 && 竞赛已交卷
function isFinishContest(contest) {
  const now = new Date();
  return new Date(contest.beginTime) < now && new Date(contest.endTime) > now && contest.isEnroll && selectedOption.value === 1 && contest.isFinish;
}

async function enterExam(contest) {
  try {
    await ElMessageBox.confirm(
        '确定要参加报名该竞赛吗?',
        '警告',
        {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning',
        }
    )
    const enterForm = reactive({
      contestId: contest.id
    })
    await createEnrollContestService(enterForm)
    ElMessage.success("报名竞赛成功！")
    await getContestList()
  } catch (error) {
    if (error === "cancel") {
    }
  }
}

// 用于存储当前选择竞赛所预约的时间点列表
const remindAPPTimeList = ref([])
const remindSMSTimeList = ref([])

// 存储当前选择的竞赛ID值
const selectContestValue = reactive({
  contestId: ''
})

// 打开预约提醒弹窗
async function openReminderDialog(contest) {
  reminderDialogVisible.value = true; // 显示弹窗
  selectContestValue.contestId = contest.id; // 设置当前竞赛ID

  // 重置表单默认值和提醒列表
  resetReminderForm();
}

// 重置表单默认值和提醒时间列表
function resetReminderForm() {
  reminderForm.notificationMethod = ''; // 清空通知方式
  reminderForm.reminderTime = '';       // 清空提醒时间
  remindAPPTimeList.value = [];         // 清空APP提醒时间列表
  remindSMSTimeList.value = [];         // 清空SMS提醒时间列表
}

// 关闭预约提醒弹窗并重置表单
function closeReminderDialog() {
  reminderDialogVisible.value = false; // 隐藏弹窗
  resetReminderForm(); // 重置表单数据
}

// 加载预约时间列表（根据用户选择的类型）
async function loadReminderTimes(type) {
  try {
    const result = await someRemindContestService({contestId: selectContestValue.contestId});

    // 确保后端返回的数据格式正确
    remindAPPTimeList.value = result.data.remindAPPTime || [];
    remindSMSTimeList.value = result.data.remindSMSTime || [];

    if (type === 'app') {
      reminderForm.reminderTime = remindAPPTimeList.value[0] || ''; // 默认选择APP的第一个时间点
    } else if (type === 'sms') {
      reminderForm.reminderTime = remindSMSTimeList.value[0] || ''; // 默认选择SMS的第一个时间点
    }
  } catch (error) {
    console.error('加载预约提醒时间失败:', error);
    remindAPPTimeList.value = [];
    remindSMSTimeList.value = [];
    reminderForm.reminderTime = ''; // 清空提醒时间
  }
}

// 检查当前时间点是否已预约
function isTimeBooked(type, time) {
  if (type === 'app') {
    return remindAPPTimeList.value.includes(time);
  } else if (type === 'sms') {
    return remindSMSTimeList.value.includes(time);
  }
  return false;
}

// 处理通知方式的变化
async function handleNotificationMethodChange() {
  // 加载对应类型的提醒时间列表
  if (reminderForm.notificationMethod) {
    await loadReminderTimes(reminderForm.notificationMethod);
  }
}

// 保存预约提醒
async function saveReminder() {
  if (!reminderForm.notificationMethod) {
    ElMessage.error('请选择通知方式！');
    return;
  }
  if (!reminderForm.reminderTime) {
    ElMessage.error('请选择提醒时间！');
    return;
  }

  const type = reminderForm.notificationMethod === 'app' ? 0 : 1;

  try {
    const remindForm = {
      contestId: selectContestValue.contestId,
      type,
      remindTime: reminderForm.reminderTime,
    };

    await createRemindContestService(remindForm);
    ElMessage.success('预约竞赛提醒成功');

    // 重新加载预约时间列表
    await loadReminderTimes(reminderForm.notificationMethod);

    // 关闭弹窗
    closeReminderDialog();
  } catch (error) {
    console.error('预约提醒失败:', error);
  }
}

// 取消预约提醒
async function cancelReminder() {
  if (!reminderForm.notificationMethod) {
    ElMessage.error('请选择通知方式！');
    return;
  }
  if (!reminderForm.reminderTime) {
    ElMessage.error('请选择已预约的提醒时间！');
    return;
  }

  const type = reminderForm.notificationMethod === 'app' ? 0 : 1;

  try {
    const remindForm = {
      contestId: selectContestValue.contestId,
      type,
      remindTime: reminderForm.reminderTime,
    };

    await cancelRemindContestService(remindForm);
    ElMessage.success('取消竞赛预约提醒成功');

    // 重新加载预约时间列表
    await loadReminderTimes(reminderForm.notificationMethod);

    // 关闭弹窗
    closeReminderDialog();
  } catch (error) {
    console.error('取消提醒失败:', error);
  }
}

// 取消用户报名竞赛
async function cancelEnterExam(id) {
  try {
    await ElMessageBox.confirm(
        '确定要取消该竞赛报名吗?',
        '警告',
        {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning',
        }
    )
    const cancelForm = reactive({
      contestId: id
    })
    await cancelEnrollContestService(cancelForm)
    ElMessage.success("取消竞赛报名成功")
    await getContestList()
  } catch (error) {
    if (error === "cancel") {
    }
  }
}

// 跳转到竞赛答题页面
function goExam(contest) {
  router.push(`/user/answer?contestId=${contest.id}&contestTitle=${contest.title}&contestEndTime=${contest.endTime}`)
}

// 处理竞赛分页查询请求
function handleContestSizeChange() {
  params.current = 1
  params.type = selectedOption.value
  getContestList()
}

function handleContestCurrentChange() {
  params.type = selectedOption.value
  getContestList()
}

const datetimeRange = ref([])

function onDateChangeSearch() {
  if (datetimeRange.value[0] instanceof Date) {
    params.beginTime = datetimeRange.value[0].toISOString()
  }
  if (datetimeRange.value[1] instanceof Date) {
    params.endTime = datetimeRange.value[1].toISOString()
  }
  params.type = selectedOption.value
}

function onReset() {
  params.type = selectedOption.value
  params.beginTime = ""
  params.endTime = ""
  params.current = 1
  params.size = 9
  datetimeRange.value.length = 0
  getContestList()
}

function onSearch() {
  getContestList()
}
</script>

<template>
  <div class="exam-page flex-col">
    <div class="exam-selected-section flex-col">
      <div class="exam-option-group flex-row justify-between">
        <div class="exam-option" v-for="option in options" :key="option.value" @click="selectOption(option.value)"
             :class="{ selected: selectedOption === option.value }">
          {{ option.label }}
        </div>
      </div>
      <div class="center-box">
        <el-form inline="true" class="exam-navigation flex-row justify-between">
          <el-form-item label="竞赛时间" prop="datetimerange" class="exam-navigation-box">
            <el-date-picker @change="onDateChangeSearch" style="width:360px;" v-model="datetimeRange"
                            type="datetimerange"
                            range-separator="至"
                            start-placeholder="开始时间" end-placeholder="结束时间"></el-date-picker>
          </el-form-item>
          <el-form-item>
            <el-button @click="onSearch" plain type="info">搜索</el-button>
            <el-button @click="onReset" plain type="info">重置</el-button>
          </el-form-item>
        </el-form>
        <div class="exam-list-group flex-row">
          <div class="exam-list-item flex-col" v-for="(contest, index) in contestList" :key="index">
            <div>
              <img src="@/assets/images/exam.png">
            </div>
            <div class="right-info">
              <div class="title-container">
                <span class="exam-title">{{ contest.title }}</span>
                <el-tag v-if="contest.isEnroll" type="success" class="registration-status-tag">
                  已报名
                </el-tag>
                <el-tag v-else type="info" class="registration-status-tag">
                  未报名
                </el-tag>
              </div>
              <div class="exam-content flex-col justify-between">
                <span>开赛时间：{{ contest.beginTime }}</span>
                <span>结束时间：{{ contest.endTime }}</span>
              </div>
              <div class="exam-button-container">
                <span class="exam-hash-entry" v-if="isOngoingAndUnregisteredCompetition(contest)">已开赛</span>
                <span class="exam-hash-finish" v-if="isFinishContest(contest)">已交卷（等待结果统计）</span>
                <el-button class="exam-start-button" type="primary" plain v-else-if="isStartExam(contest)"
                           @click="goExam(contest)">开始答题
                </el-button>
                <el-button class="exam-practice-button" type="primary" plain v-if="isEnrollContest(contest)"
                           @click="openReminderDialog(contest)">预约提醒
                </el-button>
                <el-button class="exam-enter-button" type="primary" plain v-if="isCancelEntry(contest)"
                           @click="cancelEnterExam(contest.id)">取消报名
                </el-button>
                <el-button class="exam-rank-button" type="primary" plain v-if="checkContestRanking(contest)"
                           @click="togglePopover(contest.id)">结果详情
                </el-button>
                <el-button class="exam-enter-button" type="primary" plain v-if="isCanEntry(contest)"
                           @click="enterExam(contest)">报名参赛
                </el-button>
              </div>
            </div>
          </div>
        </div>
        <div class="exam-page-pagination flex-row">
          <el-pagination background layout="total, sizes, prev, pager, next, jumper"
                         :total="totalSize"
                         v-model:current-page="params.current"
                         v-model:page-size="params.size"
                         :page-sizes="[3, 6, 9, 12]"
                         @size-change="handleContestSizeChange"
                         @current-change="handleContestCurrentChange"/>
        </div>
      </div>
    </div>
  </div>

  <!-- 竞赛结果详情弹出框-->
  <el-dialog v-model="dialogVisible" width="600px" top="30vh" :show-close="true" :close-on-click-modal="false"
             :close-on-press-escape="false" class="oj-login-dialog-centor" center>
    <el-table :data="examRankList">
      <el-table-column label="排名" prop="examRank"/>
      <el-table-column label="用户昵称" prop="nickName"/>
      <el-table-column label="用户得分" prop="score"/>
    </el-table>
    <el-pagination class="range_page" background layout="total, sizes, prev, pager, next, jumper"
                   :total="rankTotal"
                   v-model:current-page="rankParams.pageNum"
                   v-model:page-size="rankParams.pageSize"
                   :page-sizes="[1, 5, 10, 15, 20]"
                   @size-change="handleRankSizeChange"
                   @current-change="handleRankCurrentChange"/>
  </el-dialog>

  <!-- 预约提醒弹出框 -->
  <el-dialog title="预约提醒" v-model="reminderDialogVisible" width="600px">
    <el-form :model="reminderForm">
      <el-form-item label="通知方式">
        <el-radio-group v-model="reminderForm.notificationMethod" @change="handleNotificationMethodChange">
          <el-radio label="app">APP站内通知</el-radio>
          <el-radio label="sms">短信通知</el-radio>
        </el-radio-group>
      </el-form-item>

      <el-form-item label="提醒时间" class="selected-remind">
        <el-row>
          <el-col :span="18">
            <!-- 时间选择器-->
            <el-select v-model="reminderForm.reminderTime" :disabled="!reminderForm.notificationMethod"
                       placeholder="选择提醒时间" style="width: 150px;"
                       @change="handlerReminderChange">
              <el-option v-for="time in reminderTimes" :key="time" :label="`${time}分钟`" :value="time"/>
            </el-select>
          </el-col>
          <!-- 取消预约按钮 -->
          <el-col :span="6" class="cancel-button-col">
            <div v-if="isTimeBooked(reminderForm.notificationMethod,reminderForm.reminderTime)">
              <!-- 显示取消预约按钮 -->
              <el-button type="danger" @click="cancelReminder">取消预约</el-button>
            </div>
            <div v-else>
              <!-- 仅未预约时显示未预约标签 -->
              <el-tag type="info" disable-transitions class="selected-un-remind">未预约</el-tag>
            </div>
          </el-col>
        </el-row>
      </el-form-item>

      <div slot="footer" class="dialog-footer">
        <el-button @click="closeReminderDialog">取消</el-button>
        <el-button type="primary" @click="saveReminder">预约</el-button>
      </div>
    </el-form>
  </el-dialog>
</template>

<style lang="scss" scoped>
.exam-page {
  background-color: rgba(255, 255, 255, 1);
  position: relative;
  overflow: hidden;
  display: flex;
  margin-top: 20px;

  .center-box {
    max-width: 1520px;
    margin: 0 auto;
    width: 100%;
    min-height: 368px;
    background: #FFFFFF;
    border-radius: 16px;
    padding-top: 10px;
  }

  .exam-selected-section {
    margin: 0 auto;
    margin-bottom: 20px;
    position: relative;
    padding-top: 50px;
    max-width: 1520px;
    width: 100%;

    .exam-option-group {
      width: fit-content;
      height: 50px;
      position: absolute;
      top: 0;
      left: 0;

      .exam-option {
        cursor: pointer;
        padding: 10px;
        border-bottom: 2px solid transparent;
        transition: all 0.3s ease;
        font-family: PingFangSC, PingFang SC;
        font-weight: 600;
        font-size: 18px;
        color: #222;
        height: 50px;
        width: fit-content;
        display: flex;
        justify-content: center;
        align-items: center;
        margin-right: 20px;
      }

      .exam-option.selected {
        color: #32C5FF;
        border-bottom: 2px solid #32C5FF;
      }
    }

    :deep(.exam-navigation) {
      width: 554px;
      height: 40px;
      font-size: 100px;
      margin-bottom: 30px;

      .el-form-item {
        margin-right: 20px;
      }

      .el-form-item__label {
        background: #fff;
      }

      .exam-navigation-box {
        background-color: rgba(242, 243, 244, 1);
        border-radius: 6px;
        height: 30px;
        // width: 460px;
        font-weight: 700;
      }
    }

    .exam-list-group {
      // width: 1200px;
      flex-wrap: wrap;

      @media screen and (min-width: 1420px) {
        .exam-list-item {
          width: 32%;

          &:nth-of-type(3n) {
            margin-right: 0;
          }
        }

      }

      @media screen and (max-width: 1419px) {
        .exam-list-item {
          width: 48%;
          margin-right: 2%;

          &:nth-of-type(2n) {
            margin-right: 0;
          }
        }
      }

      @media screen and (max-width: 970px) {
        .exam-list-item {
          width: 100%;
          margin-right: 0;
        }
      }

      .exam-list-item {
        height: 220px;
        min-height: 220px;
        background: #F9F9F9;
        border-radius: 10px;
        margin-right: 2%;
        margin-bottom: 20px;
        padding: 20px;
        box-sizing: border-box;
        display: flex;
        align-items: center;
        flex-direction: row;
        justify-content: space-between;
        cursor: pointer;

        .right-info {
          width: calc(100% - 146px);
        }

        .title-container {
          display: flex;
          justify-content: space-between;
          align-items: center;
          position: relative;
          padding-right: 30px;
          width: 100%;

          .exam-title {
            flex: 1;
            height: 26px;
            font-family: PingFangSC, PingFang SC;
            font-weight: 600;
            font-size: 18px;
            color: #222222;
            line-height: 26px;
            text-align: left;
            max-width: 90%;
            overflow: hidden;
            text-overflow: ellipsis;
            white-space: nowrap;
            margin-bottom: 16px;
            display: block;
          }

          .registration-status-tag {
            position: absolute;
            right: 0;
            top: 0;
            font-size: 14px;
            line-height: 20px;
            margin-right: 10px;
          }
        }

        .registration-status-tag {
          margin-bottom: 10px;
          font-size: 14px;
        }

        .exam-content {
          margin-bottom: 26px;

          span {
            height: 22px;
            font-family: PingFangSC, PingFang SC;
            font-weight: 400;
            font-size: 16px;
            color: #666666;
            line-height: 22px;
            display: block;
            margin-bottom: 12px;
          }

        }

        img {
          width: 126px;
          height: 180px;
          border-radius: 6px;
        }

        &:hover {
          background: #fff;
          box-shadow: 0px 0px 6px 0px rgba(0, 0, 0, 0.1);

          .exam-title {
            color: #32C5FF;
          }

          .el-button {
            background: #f7f7f7;
          }
        }

        .exam-hash-entry {
          float: right;
          font-size: 18px;
          font-family: PingFangSC-Regular, PingFang SC;
          font-weight: 400;
          color: #999;
        }

        .exam-hash-finish {
          float: right;
          font-size: 18px;
          margin-left: 10px;
          font-family: PingFangSC-Regular, PingFang SC;
          font-weight: 400;
          color: #999;
        }

        .exam-button-container {
          display: flex;
          justify-content: space-between;
          /* 或者使用 flex-start 来紧密排列按钮 */
          align-items: center;
          width: 100%;
          min-height: 44px;
          margin-top: 10px;

          /* 如果需要垂直居中 */
          /* 其他样式，如外边距、内边距等 */
          .el-button {
            width: 120px;
            height: 44px;
            background: #F7F7F7;
            border-radius: 4px;
            border: 1px solid #32C5FF;
            font-family: PingFangSC, PingFang SC;
            font-weight: 400;
            font-size: 18px;
            color: #32C5FF;
            line-height: 44px;
            text-align: center;
          }
        }
      }
    }

    .exam-page-pagination {
      width: 594px;
      height: 40px;
      margin: 30px 0 73px 800px;
    }
  }
}

.dialog-footer {
  text-align: right;
}

.el-dialog {
  .el-form-item {
    margin-bottom: 20px;
  }

  .el-form-item label {
    font-weight: bold;
  }

  .el-button {
    margin: 0 10px;
  }

  .el-select {
    width: 100%;
  }

  .cancel-button-col {
    display: flex;
    align-items: center;
    justify-content: flex-end;
  }

  .selected-remind {
    margin-top: 30px;
  }

  .selected-time {
    font-size: 14px;
    color: #888;
    margin-top: 10px;
  }
}

.el-dialog .el-row {
  margin-bottom: 10px;
}

.selected-un-remind {
  margin-left: 15px;
}
</style>